<?php


class VulnStatus
{
const FAIL        = 0;
const VULN        = 1;
const VULN_NOT_MS = 2;
const PATCHED     = 3;
const NOT_VULN    = 4;
const NOT_VULN_MS = 5;
const NOT_VULN_CF = 6;

public static function AsString( $status, $host )
{
switch( $status )
{
case self::FAIL       : return ';<div class="alert alert-warning">无法连接到 <b>'; . $host . ';</b> 测试漏洞。</div>';;
case self::VULN       : return ';<div class="alert alert-danger"><b>'; . $host . ';</b> 存在漏洞。</div>';;
case self::VULN_NOT_MS: return ';<div class="alert alert-warning"><b>'; . $host . ';</b> 可能存在漏洞，但它好像没使用IIS。</div>';;
case self::PATCHED    : return ';<div class="alert alert-success"><b>'; . $host . ';</b> 已修复。</div>';;
case self::NOT_VULN   : return ';<div class="alert alert-info">不能识别补丁状态 <b>'; . $host . ';</b>, 并没有使用IIS，可能不存在漏洞。</div>';;
case self::NOT_VULN_MS: return ';<div class="alert alert-info">不能识别补丁状态 <b>'; . $host . ';</b>. 可能不存在漏洞。</div>';;
case self::NOT_VULN_CF: return ';<div class="alert alert-success"><b>'; . $host . ';</b> 可能使用了CloudFlare CDN加速，导致漏洞无法检测或不存在。</div>';;
}

return ';好像坏了';;
}
}

$host = false;
$status = false;
$url = filter_input( INPUT_GET, ';host';, FILTER_SANITIZE_URL );

if( !empty( $url ) && parse_url( $url, PHP_URL_SCHEME ) === null )
{
$url = ';http://'; . $url;
}

$port = parse_url( $url, PHP_URL_PORT );

if( $port === null )
{
$port = 80;
}

$url = parse_url( $url, PHP_URL_HOST );

if( $url !== null )
{
$cachekey = ';ms15034_'; . $url . ';_'; . $port;
$cachetime = 300; // 5 minutes

$host = htmlspecialchars( $url, ENT_HTML5 );

if( $port !== 80 )
{
$host .= ';:'; . $port;
}

$memcached = new Memcached( );
$memcached->addServer( ';/var/run/memcached/memcached.sock';, 0 );

$status = $memcached->get( $cachekey );

if( $status === false )
{
$fp = @fsockopen( $url, $port, $errno, $errstr, 5 );

if( $fp === false )
{
$status = VulnStatus::FAIL;
}
else
{
stream_set_timeout( $fp, 5 );

$header = "GET / HTTP/1.1\r\n";
$header .= "Host: stuff\r\n";
$header .= "Range: bytes=0-18446744073709551615\r\n";
$header .= "Connection: close\r\n\r\n";

fwrite( $fp, $header );

$response = fread( $fp, 1024 );

fclose( $fp );

if( strpos( $response, ';您的请求范围不符合'; ) !== false )
{
$status = strpos( $response, ';Microsoft'; ) === false ? VulnStatus::VULN_NOT_MS : VulnStatus::VULN;
}
else if( strpos( $response, ';请求一个无效的header头部'; ) !== false )
{
$cachetime = 3600; // 缓存时间
$status = VulnStatus::PATCHED;
}
else if( strpos( $response, ';Microsoft'; ) === false )
{
if( strpos( $response, ';403 Forbidden'; ) !== false && strpos( $response, ';cloudflare-nginx'; ) !== false )
{
$status = VulnStatus::NOT_VULN_CF;
}
else
{
$status = VulnStatus::NOT_VULN;
}
}
else
{
$status = VulnStatus::NOT_VULN_MS;
}
}

unset( $fp, $header, $response );

$memcached->set( $cachekey, $status, $cachetime );
}

$status = VulnStatus::AsString( $status, $host );
}
?>
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="theme-color" content="#424242">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>MS15-034 测试</title>

<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">

<style type="text/css">
.container {
max-width: 900px;
}

.masthead {
position: relative;
padding: 20px 0;
text-align: center;
color: #fff;
background-color: #424242;
margin-bottom: 20px;
}

.masthead a {
color: #fff;
}

.footer {
text-align: center;
padding: 15px;
color: #555;
}

.footer span {
color: #FA5994;
}

.form-inline {
text-align: center;
margin-bottom: 20px;
}

.github {
position: absolute;
top: 0;
right: 0;
}
</style>
</head>
<body>
<div>
<div>
<h1>HTTP.sys 堆栈漏洞测试</h1>
<h3>输入一个URL或主机名来测试服务器的 <a href="https://technet.microsoft.com/en-us/library/security/ms15-034.aspx" target="_blank">MS15-034</a> / <a href="http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1635" target="_blank">CVE-2015-1635</a>.</h3>
</div>
</div>



<div>
<blockquote>
<p>在HTTP协议栈（HTTP.sys）造成当HTTP协议堆栈不正确地分析特制的HTTP请求的远程代码执行漏洞。成功利用此漏洞谁的攻击者可以在系统帐户的上下文中执行任意代码。</p>
<p>要利用此漏洞，攻击者必须发送一个特制的HTTP请求发送到受影响的系统。此更新通过修改Windows HTTP协议栈处理请求解决该漏洞。</p>
</blockquote>

<form id="js-form" method="GET">
<div>
<input type="text" class="form-control input-lg" id="js-input" placeholder="baidu.com" name="host" autofocus<?php if( $host !== false ) { echo '; value="'; . $host . ';"';; } ?>>
<button type="submit" class="btn btn-primary btn-lg">检测</button>
</div>
</form>

<?php if( $status !== false ) { echo $status; } ?>

<div>使用Memcached分布式内存对象缓存系统 | 所有的结果查询会被缓存五分钟</div>
</div>
</body>
</html>